package com.definity.toolkit.ui.widget;

import java.awt.Component;
import java.awt.Container;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;

import com.definity.toolkit.ui.Body;
import com.definity.toolkit.ui.action.ActionExecutor;
import com.definity.toolkit.ui.widget.support.CalendarSupport;

public class WidgetBuilder {

	private final Map<String, ActionExecutor> bindings = new HashMap<String, ActionExecutor>();
	
	public WidgetBuilder() {

	}
	
	public final void bind(String id, ActionExecutor executor) {
		bindings.put(id, executor);
	}

	public final void unbind(String id) {
		bindings.remove(id);
	}
	
	public Panel panel(Body<Panel> body) {
		Panel panel = new Panel();
		body.content(panel);
		return panel;
	}

	public Panel panel() {
		Panel panel = new Panel();
		return panel;
	}
	
	public DockPanel dock() {
		return new DockPanel();
	}
	
	public ShadowPanel shadowPanel(Body<BorderPanel> body) {
		return new ShadowPanel().content(body);
	}
	
	public BorderPanel borderPanel() {
		return new BorderPanel();
	}
	
	public BorderPanel borderPanel(Body<BorderPanel> body) {
		BorderPanel borderPanel = new BorderPanel();
		body.content(borderPanel);
		return borderPanel;
	}

	public TablePanel tablePanel(int rows, int cols) {
		return new TablePanel(rows, cols);
	}
	
	public GridPanel gridPanel() {
		return new GridPanel();
	}
	
	public GridPanel gridPanel(Body<GridPanel> body) {
		GridPanel gridPanel = new GridPanel();
		body.content(gridPanel);
		return gridPanel;
	}

	public Panel boxLayout(int axis) {
		Panel panel = new Panel();
		panel.setLayout(new BoxLayout(panel, axis));
		return panel;
	}
	
	public Scroll scroll(Component component) {
		return new Scroll(component);
	}
	
	public List list() {
		return new List();
	}
	
	public Label label() {
		return new Label().action(executor());
	}

	public Label label(String text) {
		return new Label(text).action(executor());
	}

	public Label label(Icon icon) {
		return new Label(icon).action(executor());
	}
	
	public Button button(String text) {
		return new Button(text).action(executor());
	}

	public Button button(Icon icon) {
		return new Button(icon).action(executor());
	}

	public TextField textField() {
		return new TextField();
	}

	public TextField textField(String text) {
		return new TextField(text);
	}
	
	public PasswordField passwordField() {
		return new PasswordField();
	}
	
	public TextArea textArea() {
		return new TextArea();
	}
	
	@SuppressWarnings("unchecked")
	public <C extends JComponent> C find(Container c, String id) {
		return (C) WidgetUtils.find(c, id);
	}
	
	public MenuBar menuBar() {
		return new MenuBar();
	}

	public Menu menu(String text) {
		return new Menu(text);
	}

	public MenuItem menuItem(String text) {
		return new MenuItem(text).action(executor());
	}

	public ProgressBar progressBar() {
		return new ProgressBar();
	}
	
	public CalendarPanel calendar() {
		return new CalendarPanel();
	}

	public CalendarPanel calendar(CalendarSupport calendar) {
		return new CalendarPanel(calendar);
	}

	public DesktopPane desktopPane() {
		return new DesktopPane();
	}

	public ActionExecutor executor() {
		return new ActionExecutor() {
			@Override
			public void execute(JComponent c) {
				ActionExecutor executor = bindings.get(c.getName());
				if (executor != null)
					executor.execute(c);
			}
		};
	}

	public Icon icon(String url) {
		return WidgetUtils.icon("images/"+ url + ".png");
	}
	
	public void invokeLater(Runnable runnable) {
		SwingUtilities.invokeLater(runnable);
	}

	public void invokeAndWait(Runnable runnable) throws InterruptedException, InvocationTargetException {
		SwingUtilities.invokeAndWait(runnable);
	}

}